package com.hengpeng.itfin.service.account.impl;

import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.hengpeng.common.persist.query.DynamicQuery;
import com.hengpeng.common.util.BeanClone;
import com.hengpeng.itfin.service.ServiceFactory;
import com.hengpeng.itfin.service.account.AccountService;
import com.hengpeng.itfinbase.en.AccountType;
import com.hengpeng.itfinbase.en.TradeMode;
import com.hengpeng.itfinbase.en.TransType;
import com.hengpeng.itfinbase.persist.Account;
import com.hengpeng.itfinbase.persist.AccountLog;

@Lazy
@Service
@Transactional
public class AccountServiceImpl implements AccountService
{
	@Autowired
	private ServiceFactory serviceFactory;

	@Override
	public List<Account> queryPlatFormList()
	{
		DynamicQuery query = new DynamicQuery(Account.class);
		query.eq("accountType", AccountType.PLATFORM);
		return serviceFactory.getPersistService().findByDynamicQuery(Account.class, query);
	}

	@Override
	public Account lockAccount(Long userId)
	{
		DynamicQuery query = new DynamicQuery(Account.class);
		query.eq("userId", userId);
		Account account = serviceFactory.getPersistService().getByDynamicQuery(Account.class, query);
		if (account != null)
		{
			account = serviceFactory.getPersistService().lockObject(Account.class, account.getId());
		}
		return account;
	}

	@Override
	public Account getAccount(Long userId)
	{
		DynamicQuery query = new DynamicQuery(Account.class);
		query.eq("userId", userId);
		return serviceFactory.getPersistService().getByDynamicQuery(Account.class, query);
	}

	@Override
	public void changeAccountMoney(Long userId, Long money, TransType transType, TradeMode tradeMode,
			String referenceId, String remark)
	{
		changeAccountMoney(userId, money, 0L, 0L, transType, tradeMode, referenceId, remark);
	}

	@Override
	public void changeAccountMoney(Long userId, Long totalMoney, Long baseMoney, Long interestMoney,
			TransType transType, TradeMode tradeMode, String referenceId, String remark)
	{
		Account account = serviceFactory.getAccountService().lockAccount(userId);
		Account beforeAccount = BeanClone.clone(account, Account.class);// 保留交易前数据
		if (tradeMode == TradeMode.ADD)
		{// 加钱操作
			account.setBaseMoney(account.getBaseMoney() + totalMoney);
			switch (transType)
			{
				case IMPREST:// 充值
					account.setTotalfillMoney(account.getTotalfillMoney() + totalMoney);// 更新累计充值字段
					break;
				case REPAYMENT:// 标的还款
				case ADDMONEY:// 标的还款(附加利息,投资人收取)
					account.setTotalIncomeMoney(account.getTotalIncomeMoney() + interestMoney);// 更新累计收益金额
					account.setBaseMoneyCollect(account.getBaseMoneyCollect() - baseMoney);// 更新待收本金金额
					account.setInComeMoneyCollect(account.getInComeMoneyCollect() - interestMoney);// 更新待收收益金额
					break;
			}
		}
		else if (tradeMode == TradeMode.SUBTRACT)
		{// 减钱操作
			account.setBaseMoney(account.getBaseMoney() - totalMoney);
			switch (transType)
			{
				case DRAW:// 提现
					account.setTotaldrawMoney(account.getTotaldrawMoney() + totalMoney);
					break;
				case REPAYMENT:// 标的还款
					account.setBaseMoneyRepay(account.getBaseMoneyRepay() - baseMoney);// 更新待还本金总额
					account.setInterestMoneyRepay(account.getInterestMoneyRepay() - interestMoney);// 更新待还利息总额
					break;
				case PAYBACK:// 用户偿还垫付
					account.setBaseMoneyRepay(account.getBaseMoneyRepay() - baseMoney);// 更新待还本金总额
					account.setInterestMoneyRepay(account.getInterestMoneyRepay() - interestMoney);// 更新待还利息总额
					break;
			}
		}
		else if (tradeMode == TradeMode.FREEZE)
		{
			// 冻结操作
			account.setFreezeMoney(account.getFreezeMoney() + totalMoney);
			switch (transType)
			{
				case INVEST:// 投标
					// 投标时暂时只更新资金表中的冻结金额,累计投资金额,累计投资笔数。 待收本金,待收收益在投标放款的时候进行更新。放款失败或撤标时需要减少累计投资金额,累计投资笔数
					account.setTotalInvestMoney(account.getTotalInvestMoney() + totalMoney);
					account.setTotalInvestNum(account.getTotalInvestNum() + 1);
					break;
			}
		}
		else if (tradeMode == TradeMode.UNFREEZE)
		{// 解冻操作
			account.setFreezeMoney(account.getFreezeMoney() - totalMoney);
			switch (transType)
			{
				case CANCLE:// 撤标
					// 撤标流标资金解冻,减少对应累计投资笔数和累计投资额
					account.setTotalInvestMoney(account.getTotalInvestMoney() - totalMoney);
					account.setTotalInvestNum(account.getTotalInvestNum() - 1);
					break;
			}
		}
		account.setUpdateTime(new Date());

		/** 添加资金操作日志 */
		AccountLog accountLog = new AccountLog();
		accountLog.setUserId(userId);
		accountLog.setUserName(account.getUserName());
		accountLog.setTrustAccountId(account.getTrustAccountId());
		accountLog.setTransType(transType);
		accountLog.setAccountType(account.getAccountType());
		accountLog.setReferenceId(referenceId);
		accountLog.setMoney(totalMoney);
		accountLog.setTransTime(new Date());
		accountLog.setTradeMode(tradeMode);
		accountLog.setRemark(remark);
		accountLog.setCreateTime(new Date());
		accountLog.setUpdateTime(new Date());
		accountLog.setBaseMoney(beforeAccount.getBaseMoney());// 交易前本金
		accountLog.setRemnantBaseMoney(account.getBaseMoney());// 交易后本金
		accountLog.setRemnantFreezeMoney(account.getFreezeMoney());// 交易后冻结资金

		serviceFactory.getPersistService().update(account);
		serviceFactory.getPersistService().save(accountLog);
	}

	@Override
	public void loansChangeAccountMoney(Long userId, Long totalMoney, Long baseMoney, Long interestMoney,
			TransType transType, TradeMode tradeMode, String referenceId, String remark, boolean addTotal)
	{
		Account account = serviceFactory.getAccountService().lockAccount(userId);
		Account beforeAccount = BeanClone.clone(account, Account.class);// 保留交易前数据
		switch (tradeMode)
		{
			case ADD:
				account.setBaseMoney(account.getBaseMoney() + totalMoney);// 加钱操作
				if (transType == TransType.LOAN)
				{
					if (addTotal)
					{
						// 借款人加钱，需要更新待还本金和利息
						account.setBaseMoneyRepay(account.getBaseMoneyRepay() + baseMoney);// 更新待还本金总额
						account.setInterestMoneyRepay(account.getInterestMoneyRepay() + interestMoney);// 更新待还利息总额
					}
				}
				break;
			case SUBTRACT:
				account.setBaseMoney(account.getBaseMoney() - totalMoney);// 减钱操作
				if (transType == TransType.LOAN)
				{
					if (addTotal)
					{
						// 投资人转出资金，需要更新待收时本金和待收收益
						account.setBaseMoneyCollect(account.getBaseMoneyCollect() + baseMoney);// 更新待收本金金额
						account.setInComeMoneyCollect(account.getInComeMoneyCollect() + interestMoney);// 更新待收收益金额
					}
				}
				break;
			case FREEZE:
				// 冻结操作
				account.setFreezeMoney(account.getFreezeMoney() + totalMoney);
				break;
			case UNFREEZE:
				// 解冻操作
				account.setFreezeMoney(account.getFreezeMoney() - totalMoney);
				break;
		}
		account.setUpdateTime(new Date());
		/** 添加资金操作日志 */
		AccountLog accountLog = new AccountLog();
		accountLog.setUserId(userId);
		accountLog.setUserName(account.getUserName());
		accountLog.setTrustAccountId(account.getTrustAccountId());
		accountLog.setAccountType(account.getAccountType());
		accountLog.setTransType(transType);
		accountLog.setReferenceId(referenceId);
		accountLog.setMoney(totalMoney);
		accountLog.setTransTime(new Date());
		accountLog.setTradeMode(tradeMode);
		accountLog.setRemark(remark);
		accountLog.setCreateTime(new Date());
		accountLog.setUpdateTime(new Date());
		accountLog.setBaseMoney(beforeAccount.getBaseMoney());// 交易前本金
		accountLog.setRemnantBaseMoney(account.getBaseMoney());// 交易后本金
		accountLog.setRemnantFreezeMoney(account.getFreezeMoney());// 交易后冻结资金

		serviceFactory.getPersistService().update(account);
		serviceFactory.getPersistService().save(accountLog);
	}

	@Override
	public void freeze(Long userId, TransType transType, Long money, String referenceId, String remark)
	{
		changeAccountMoney(userId, money, transType, TradeMode.FREEZE, referenceId, remark);
	}

	@Override
	public void unfreezeForSuc(Long userId, TransType transType, Long money, String referenceId, String remark)
	{
		changeAccountMoney(userId, money, transType, TradeMode.UNFREEZE, referenceId, remark + ",解冻");
		changeAccountMoney(userId, money, transType, TradeMode.SUBTRACT, referenceId, remark + ",扣款");
	}

	@Override
	public void unfreezeForFail(Long userId, TransType transType, Long money, String referenceId, String remark)
	{
		changeAccountMoney(userId, money, transType, TradeMode.UNFREEZE, referenceId, remark);
	}

	@Override
	public void add(Long userId, TransType transType, Long money, String referenceId, String remark)
	{
		changeAccountMoney(userId, money, transType, TradeMode.ADD, referenceId, remark);
	}

	@Override
	public void subtractNoFreeze(Long userId, TransType transType, Long money, String referenceId, String remark)
	{
		changeAccountMoney(userId, money, transType, TradeMode.SUBTRACT, referenceId, remark);
	}

}
